package com.sirap.spring.boot.demo.controller.album;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sirap.basic.component.Konstants;
import com.sirap.basic.search.FileSizeCriteria;
import com.sirap.basic.search.SizeCriteria;
import com.sirap.basic.tool.C;
import com.sirap.basic.tool.D;
import com.sirap.basic.util.Amaps;
import com.sirap.basic.util.DateUtil;
import com.sirap.basic.util.EmptyUtil;
import com.sirap.basic.util.FileUtil;
import com.sirap.basic.util.IOUtil;
import com.sirap.basic.util.ImageUtil;
import com.sirap.basic.util.RandomUtil;
import com.sirap.basic.util.StrUtil;
import com.sirap.basic.util.ThreadUtil;
import com.sirap.basic.util.XCodeUtil;
import com.sirap.basic.util.XXXUtil;
import com.sirap.common.domain.Album;
import com.sirap.fish.FishFileHelper;
import com.sirap.spring.boot.demo.config.RingUtil;
import com.sirap.spring.boot.demo.controller.BaseController;

@Controller
@RequestMapping(value = "/album")
public class AlbumController extends BaseController {

    @RequestMapping(value = "/list", method = RequestMethod.GET)
	public String listAllAlbums(HttpServletRequest request, HashMap<String, Object> map) {
    	D.at();
    	String filepath = pathOfAlbums();
    	List<Map<String, Object>> items = FishFileHelper.getImageSubFoldersFrom(filepath);
    	map.put("albumItems", items);
    	C.listSome(items, 3);
//    	D.pjsp(map);
	
		return "album/albumList";
    }

	@ResponseBody
	@RequestMapping(value = "/areaOfImage", method = RequestMethod.GET)
	public Map<String, Object> areaOfImage(HttpServletRequest request) {
		String imageHref = request.getParameter("imageHref");
		String imagePath = imageHref.replaceAll("^/storage/", "");
		D.pla(imageHref, imagePath);
		String filePath = StrUtil.useSeparator(storage(), imagePath);
		String area = ImageUtil.readImageWidthHeight(new File(filePath), ".");
		Map map = Amaps.createMap("info", area);
		
		return map;
	}

	@ResponseBody
	@RequestMapping(value = "/removeImage", method = RequestMethod.POST)
	public Map<String, Object> removeImage(HttpServletRequest request) {
		D.at();
		String imageHref = request.getParameter("imageHref");
		String imagePath = imageHref.replaceAll("^/storage/", "");
		D.pl("File to remove: " + imageHref);
		String filePath = StrUtil.useSeparator(storage(), imagePath);
		boolean flag = FileUtil.getIfNormalFile(filePath).delete();
		D.pl("File removed: " + imagePath);
		Map map = Amaps.createMap("removed", flag);
		
		return map;
	}
	
    @RequestMapping(value = "/save", method = RequestMethod.POST)
	public String saveAlbum(HttpServletRequest request, HashMap<String, Object> map) {
    	String albumName = request.getParameter("ball");
    	String oldname = request.getParameter("oldname");
    	String strIsedit = request.getParameter("isedit");
    	boolean isedit = Boolean.parseBoolean(strIsedit);
    	D.pla(albumName, strIsedit, isedit);
    	D.pjsp(request.getParameterMap());
    	String tempName;
    	String albumPath;
    	if(isedit) {
    		tempName = oldname;
    		XXXUtil.shouldBeNotEmpty(tempName);
    		albumPath = StrUtil.useSeparator(pathOfAlbums(), tempName.trim());
    	} else {
    		//add new
    		tempName = albumName;
    		if(EmptyUtil.isNullOrEmptyOrBlank(tempName)) {
        		tempName = DateUtil.timestamp() + "_" + RandomUtil.name(999);
    		} else {
    			tempName = tempName.trim();
    			String tempPath = StrUtil.useSeparator(pathOfAlbums(), tempName);
    			if(FileUtil.exists(tempPath)) {
    				tempName = DateUtil.timestamp() + "_" + RandomUtil.name(999) + "_" + tempName;
    			}
    		}
    	}
    	
		albumPath = StrUtil.useSeparator(pathOfAlbums(), tempName);
    	FileUtil.makeDirectories(albumPath);
    	
    	String param = XCodeUtil.urlEncodeUTF8(tempName).replace("+", "%20");
    	String redirecto = "/album/" + param + "/show";
    	
    	if(MultipartHttpServletRequest.class.isInstance(request)) {
			MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest)request;
			RingUtil.saveFiles(mrequest, albumPath);
		}
    	
    	return redirect(redirecto);
	}
    
    @RequestMapping(value = "/create", method = RequestMethod.GET)
	public String pageToCreate() {
    	return "album/albumEdit";
    }
    
    @RequestMapping(value = "/create/{albumName}", method = RequestMethod.GET)
	public String pageToCreateWithName(@PathVariable String albumName, HashMap<String, Object> map) {
    	map.put("albumName", albumName);
    	return "album/albumEdit";
    }
    
    @RequestMapping(value = "/{albumName}/edit", method = RequestMethod.GET)
	public String editAlbum(@PathVariable String albumName, HttpServletRequest request, HashMap<String, Object> map) {
    	map.put("albumName", albumName);
    	map.put("isedit", true);
    	
    	return "album/albumEdit";
    }
    
    @RequestMapping(value = "/{albumName}/show", method = RequestMethod.GET)
	public String showAlbumByName(@PathVariable String albumName, HttpServletRequest request, HashMap<String, Object> map) {
    	D.at();
    	String targetsize = "200K";
    	String criteria = "<" + targetsize;
    	String smallFileSize = StrUtil.occupy("< {0}B ≤", targetsize);
    	String filePath = StrUtil.useSeparator(pathOfAlbums(), albumName);
    	int countOfSmall = 0, countOfBig = 0;
    	long sizeOfSmall = 0, sizeOfBig = 0;
    	if(FileUtil.exists(filePath)) {
    		String hrefPrefix = StrUtil.useSeparator("/storage", "albums", albumName);
    		List<Map<String, Object>> images = Lists.newArrayList();
    		List<File> files = FileUtil.getSubFilesByLastModifiedDescend(filePath);
    		long totalSize = 0;
    		for(File file : files) {
    			String type = "ftype";
    			String imagename = file.getName();
    			String extension = FileUtil.extensionOf(imagename);
        		if(StrUtil.isIn(extension, FileUtil.EXTENSIONS_IMAGE)) {
        			type = "image";
        		} else if(StrUtil.isIn(extension, FileUtil.EXTENSIONS_VIDEO)) {
        			type = "video";
        		} else {
        			continue;
        		}
    			String href = StrUtil.useSeparator(hrefPrefix, imagename);
    			Map<String, Object> image = Maps.newConcurrentMap();
    			image.put("href", href);
    			image.put("name", imagename);
    			image.put("size", FileUtil.formatSize(file.length()));
    			SizeCriteria so = new FileSizeCriteria(criteria);
    			boolean isSmallFile = so.isGood(file.length());
    			if(isSmallFile) {
    				countOfSmall++;
    				sizeOfSmall += file.length();
    			} else {
    				countOfBig++;
    				sizeOfBig += file.length();
    			}
    			image.put("isSmallFile", isSmallFile);
    			image.put("ftype", type);
				images.add(image);
				totalSize += file.length();
    		}

        	map.put("images", images);
        	map.put("countOfAll", images.size());
        	map.put("sizeOfAll", FileUtil.formatSize(totalSize));
        	map.put("countOfSmall", countOfSmall);
        	map.put("sizeOfSmall", FileUtil.formatSize(sizeOfSmall));
        	map.put("countOfBig", countOfBig);
        	map.put("sizeOfBig", FileUtil.formatSize(sizeOfBig));
        	map.put("smallFileSize", smallFileSize);
    	} else {
    		map.put("info", "相册不存在：" + albumName);
    	}

    	map.put("albumName", albumName);
    	map.put("issuper", isSuperUser(request));
    	
    	D.pjsp(map);
	
		return "album/albumDetail";
    }
    
    @RequestMapping(value = "/{albumName}/bk", method = RequestMethod.GET)
	public String backupAlbum(@PathVariable String albumName, HttpServletRequest request, HashMap<String, Object> map) {
    	D.at();

		String albumPath = StrUtil.useSeparator(pathOfAlbums(), albumName);
    	if(FileUtil.exists(albumPath)) {
    		String bkName = DateUtil.timestamp() + "_" + RandomUtil.name() + "_" + albumName;
    		String targetPath = StrUtil.useSeparator(storage(), "bk", bkName);
    		List<File> files = FileUtil.getSubFilesByLastModifiedAscend(albumPath);
			
			FileUtil.makeDirectories(targetPath);
    		for(File file : files) {
    			File newFile = new File(StrUtil.useSeparator(targetPath, file.getName()));
    			file.renameTo(newFile);
    		}
    		
    		FileUtil.remove(albumPath);
    		
			String redirecto = "/album/list";
    		return redirect(redirecto);
    	} else {
    		FileUtil.makeDirectories(albumPath);
    		map.put("albumName", albumName);
    		map.put("info", "相册不存在: " + albumName);
    		
    		return "album/albumDetail";
    	}
    }
    
    @RequestMapping(value = "/{albumName}/sansa", method = RequestMethod.GET)
	public String removeAlbum(@PathVariable String albumName, HttpServletRequest request, HashMap<String, Object> map) {
    	D.at();

		String albumPath = StrUtil.useSeparator(pathOfAlbums(), albumName);
    	if(FileUtil.exists(albumPath)) {
    		FileUtil.remove(albumPath);
    	}

    	String redirecto = "/album/list";
		return redirect(redirecto);
    }
    
    @RequestMapping(value = "/{albumName}/rn/{newname}", method = RequestMethod.GET)
	public String renameAlbum(@PathVariable String albumName, @PathVariable String newname, HttpServletRequest request, HashMap<String, Object> map) {
    	D.at();
		String legal = newname;
		if(StrUtil.isRegexMatched("[\\.]{1,}", newname)) {
			legal = RandomUtil.name(1000);
		}

		String albumPath = StrUtil.useSeparator(pathOfAlbums(), albumName);
    	if(FileUtil.exists(albumPath)) {
    		String targetPath = StrUtil.useSeparator(pathOfAlbums(), legal);
    		String param = XCodeUtil.urlEncodeUTF8(legal).replace("+", "%20");
    		
			FileUtil.makeDirectories(targetPath);
    		List<File> files = FileUtil.getSubFilesByLastModifiedAscend(albumPath);
    		for(File file : files) {
    			File newFile = new File(StrUtil.useSeparator(targetPath, file.getName()));
    			file.renameTo(newFile);
    		}
    		FileUtil.remove(albumPath);
    		
    		String redirecto = "/album/" + param + "/show";
    		return redirect(redirecto);
    	} else {
    		FileUtil.makeDirectories(albumPath);
    		map.put("albumName", albumName);
    		map.put("info", "相册不存在: " + albumName);
    		
    		return "album/albumDetail";
    	}
    }
    
    @RequestMapping(value = "/websave/{base64url}", method = RequestMethod.GET)
	public String saveAlbumImages(HttpServletRequest request, @PathVariable String base64url, HashMap<String, Object> map) {
    	D.at();
    	String albumurl = XCodeUtil.fromBase64(base64url);
    	D.pl(albumurl);
    	Album al = readAlbumFromCacheOrFetcher(albumurl, null);
    	if(al == null) {
    		return redirect("/albums");
    	}
    	D.pjsp(al.getLinks());
    	String albumName = al.niceName();
    	String whereToSave = StrUtil.useSeparator(pathOfAlbums(), albumName);
    	ThreadUtil.executeInNewThread(new Runnable() {
			public void run() {
		    	List<String> files = IOUtil.downloadFiles(whereToSave, al.getLinks(), Konstants.DOT_JPG);
		    	D.list(files);
			}
		});
    	ThreadUtil.sleepInSeconds(al.getLinks().size() / 10 + 2);
    	D.pla(base64url, albumurl);
		String param = XCodeUtil.urlEncodeUTF8(albumName).replace("+", "%20");
		D.pl(param);
		String albumUrl = StrUtil.occupy("/album/{0}/show", param);
    	
    	return redirect(albumUrl);
    }
}
